// 1. 对数据进行响应式处理

// 2. 劫持到数据变化，使用发布订阅模式，发布消息

// 3. 订阅： 收到消息后change state更新视图

// 使用闭包模式保存状态
function createStore(reducer, initData) {
  let state = initData;
  let listeners = [];

  const getState = () => state;

  const subscribe = (handler) => {
    listeners.push(handler);
  };

  const dispatch = (action) => {
    state = reducer(state, action);
    listeners.forEach((fn) => fn());
  };

  return {
    dispatch,
    subscribe,
    getState,
  };
}
const initData = {
  count: 1,
  age: 10,
};
const ageReducer = (state, action) => {
  const { type, payload } = action;
  switch (type) {
    case "add":
      return { age: payload };
  }
};

const countReducer = (state, action) => {
  const { type, payload } = action;
  switch (type) {
    case "add":
      return { count: payload };
  }
};

const combineReducer = (reducers) => {
  return (state, action) => {
    let prev = {};
    Object.keys(reducers).forEach((key) => {
      let nextv = reducers[key](state, action);
      prev = { ...state, ...nextv };
    });
    return prev;
  };
};

let dataObj = createStore(
  combineReducer({ age: ageReducer, count: countReducer }),
  initData
);

export default function DataIndex() {
  const [count, setCount] = useState(initData.count);
  useEffect(() => {
    dataObj.subscribe(() => {
      let curData = dataObj.getState();

      setCount(() => curData.count);
    });
  });

  const handleAdd = () => {
    dataObj.dispatch({ type: "add", payload: 23 });
  };
}

const connect = () => (Component) => {
  return (props) => {
    // 上下文
    const _store = useContext(ReduxContext);
    const [, setBool] = useState(true);
    const forceUpdate = () => {
      setBool((val) => !val);
    };
    useEffect(() => {
      _store.subscribe(forceUpdate);
    }, []);
    return (
      <ReduxContext.Consumer>
        {(store) => (
          <Component
            {...props}
            {...mapStateToProps(store.getState())}
            {...mapDispatchToProps(store.dispatch)}
          />
        )}
      </ReduxContext.Consumer>
    );
  };
};

const mapStateToProps = (state) => {};
const mapDispatchToProps = (state) => {};

connect(mapStateToProps, mapDispatchToProps)(Component);
